using System;
using NUnit.Framework;
using Rhino.Mocks;
using gnodotnet.Core.MailingList;
using SharpArch.Testing;
using SharpArch.Core.PersistenceSupport;
using gnodotnet.Web.Controllers.MailingList;
using System.Web.Mvc;
using MvcContrib.TestHelper;
using gnodotnet.Web.Controllers;
using SharpArch.Testing.NUnit;

namespace Tests.gnodotnet.Web.Controllers.MailingList {
    public class When_sending_a_message_succeeds : GivenWhenThenTests {

        private ActionResult _actionResult;
        private MessagesController _controller;
        private IMessanger _messanger;
        private IRepository<Message> _repository;
        private Message _message;
        public When_sending_a_message_succeeds() {
            given += () => {
                _message = new Message() { Subject = "Test Subject", Contents = "Contents" };
                _message.SetIdTo(10);
                _repository = MockRepository.GenerateStub<IRepository<Message>>();
                _repository.Stub(r => r.Get(10)).Return(_message);
                _messanger = MockRepository.GenerateStub<IMessanger>();
                _controller = new MessagesController(_repository, _messanger);
            };
            when += () => _actionResult = _controller.Send(_message.Id);
        }
        [Test] public void will_fetch_message_from_repository() {
            then = () => _repository.AssertWasCalled(r => r.Get(_message.Id));
        }
        [Test] public void will_pass_unsent_message_to_a_messanger() {
            then = () => _messanger.AssertWasCalled(x => x.Deliver(_message));
        }
        [Test] public void will_route_back_to_the_index() {
            then = () => _actionResult.AssertActionRedirect().ToAction("Index");
        }
        [Test] public void page_will_contain_note_that_message_was_sent() {
            then = () => _controller.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()]
                .ToString().ShouldContain("was sent");
        }
    }
    public class When_sending_a_message_fails : GivenWhenThenTests {

        private ActionResult _actionResult;
        private MessagesController _controller;
        private IMessanger _messanger;
        private IRepository<Message> _repository;
        public When_sending_a_message_fails() {
            given += () => {
                _repository = MockRepository.GenerateStub<IRepository<Message>>();
                _repository.Stub(r => r.Get(10)).Return(null);
                _messanger = MockRepository.GenerateStub<IMessanger>();
                _controller = new MessagesController(_repository, _messanger);
            };
            when += () => _actionResult = _controller.Send(10);
        }
        [Test]
        public void will_not_access_messanger() {
            then = () => _messanger.AssertWasNotCalled(x => x.Deliver(null), c=>c.IgnoreArguments());
        }
        [Test]
        public void will_remain_on_page() {
            then = () => _actionResult.AssertViewRendered();
        }
        [Test]
        public void page_will_contain_note_that_message_was_sent() {
            then = () => _controller.TempData[ControllerEnums.GlobalViewDataProperty.ErrorDescription.ToString()]
                .ToString().ShouldNotBeEmpty();
        }
    }
}
